package com.visec.hdy.file;

import java.io.File;
import java.io.InputStream;

import com.visec.hdy.hadoop.analysis.FileAnalysisImpl;
import com.visec.hdy.hadoop.context.FileReadContextImpl;
import com.visec.hdy.hadoop.context.FileWriteContextImpl;
import com.visec.hdy.hadoop.fsb.FileSystemFSB;
import com.visec.hdy.hadoop.inquiry.FileInquiryImpl;
import com.visec.hdy.hadoop.standard.Analysis;
import com.visec.hdy.hadoop.standard.FSB;
import com.visec.hdy.hadoop.standard.Inquiry;
import com.visec.hdy.hadoop.standard.Storage;
import com.visec.hdy.hadoop.storage.FileStorageImpl;

public class BaseHFile<V> implements HFile<String, V> {
	private FSB fsb;
	private Storage<String, InputStream> storage;
	private Analysis<String, V, InputStream> analysis;
	private Inquiry<String, File> inquiry;

	public BaseHFile(String folder, String key, String value) {
		this(folder, key, value, new FileSystemFSB(), SystemType.FAT32, false);
	}

	public BaseHFile(String folder, String key, String value, boolean isAppend) {
		this(folder, key, value, new FileSystemFSB(), SystemType.FAT32, isAppend);
	}

	public BaseHFile(String folder, String key, String value, SystemType type) {
		this(folder, key, value, new FileSystemFSB(), type, false);
	}

	public BaseHFile(String folder, String key, String value, FSB fsb, SystemType type, boolean isAppend) {
		this.fsb = fsb;
		this.storage = new FileStorageImpl<>(this.fsb, isAppend);
		this.analysis = new FileAnalysisImpl<>(key, value);
		this.storage.setContext(new FileWriteContextImpl(folder, type.maxSize()));
		this.inquiry = new FileInquiryImpl(fsb);
		this.inquiry.setContext(new FileReadContextImpl(folder, type.maxSize()));
	}

	public void setAnalysis(Analysis<String, V, InputStream> analysis) {
		this.analysis = analysis;
	}

	@Override
	public void save(V v) {
		this.storage.store(this.analysis.analyze(v));
	}

	@Override
	public com.visec.hdy.file.HFile.Find findAll() {
		this.inquiry.queryAll();
		return new Find(this.inquiry, this.fsb);
	}

	@Override
	public com.visec.hdy.file.HFile.Find find(String k) {
		this.inquiry.queryLike(k);
		return new Find(this.inquiry, this.fsb);
	}

	@Override
	public void close() {
		this.inquiry.clear();
		this.storage.close();
	}

}
